package com.zjj.learn.designmodel.work.visitor;

import java.util.ArrayList;
import java.util.List;

public class VisitorTest {

    public static void main(String[] args) {
        //声明三个具体的徒刑
        List<Element> elements = new ArrayList<>();
        elements.add(new Rectangle(10, 10, 100, 200));
        elements.add(new Circle(50, 50, 100));
        elements.add(new TextBox(20, 20, 300, 100));
        //声明计算面积访问器和计算周长访问器
        AreaCalculator areaCalc = new AreaCalculator();
        PerimeterCalculator perimeterCalc = new PerimeterCalculator();

        for (Element element : elements) {
            element.accept(areaCalc);
            element.accept(perimeterCalc);
            System.out.println("area = " + areaCalc.getArea());
            System.out.println("周长 = " + perimeterCalc.getPerimeter());
            //初始化 面积和周长计算器
            areaCalc = new AreaCalculator();
            perimeterCalc = new PerimeterCalculator();
            System.out.println("-------------分割-----------------");
        }

    }

    /**
     * 访问者模式
     *     访问者模式是一种行为型设计模式，它可以将算法与对象结构分离开来，使得算法可以独立于对象来变化。
     *     该模式主要解决的问题是在不修改对象自身的基础上，对对象的结构进行增删改等操作。
     *
     *      在访问者模式中，对象结构包含多个具体元素，每个具体元素都可以接受一个访问者进行访问，而访问者可以对不同的具体元素进行不同的操作。
     *     在此过程中，访问者可以通过访问具体元素所提供的接口来访问和操作具体元素。
     *
     *
     * 案例：
     *   假设我们有一个图形界面系统，其中包含多种类型的图形元素，如矩形、圆形、文本框等，这些图形元素都具有不同的属性和位置，
     *   我们希望能够根据不同的需求对这些图形元素进行不同的操作，如计算它们的面积、计算它们的周长等等。
     *
     * 1、首先我们需要定义图形元素的基本接口，包括接受访问者的方法：
     *    {@link com.zjj.learn.designmodel.work.visitor.Element}
     *
     * 2、然后我们定义几个具体的图形元素，如矩形、圆形和文本框：
     *    {@link com.zjj.learn.designmodel.work.visitor.Circle}
     *    {@link com.zjj.learn.designmodel.work.visitor.Rectangle}
     *    {@link com.zjj.learn.designmodel.work.visitor.TextBox}
     *
     * 3、接下来，我们定义一个访问者接口，包含对每个具体图形元素的访问方法：
     *    {@link com.zjj.learn.designmodel.work.visitor.Visitor}
     *
     * 4、最后，我们定义具体的访问者实现，实现访问所需的具体操作：
     *    {@link com.zjj.learn.designmodel.work.visitor.AreaCalculator}
     *    {@link com.zjj.learn.designmodel.work.visitor.PerimeterCalculator}
     *
     * 5、在客户端中，我们可以根据需要选择合适的访问者进行访问操作：
     *    {@link com.zjj.learn.designmodel.work.visitor.VisitorTest#main(String[])}
     *
     *
     * 总之，访问者模式适用于需要对一个复杂的对象结构（如树形结构）进行操作，
     * 并且需要在不改变各元素类的前提下增加新的操作的场合。
     * 它通过将具体操作封装到访问者类中，实现对被访问对象结构的访问和处理。
     **/
}
